/*
 * Copyright (c) 2009, Balazs Lecz <leczbalazs@gmail.com>
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 *     * Redistributions of source code must retain the above copyright notice,
 *       this list of conditions and the following disclaimer.
 * 
 *     * Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 * 
 *     * Neither the name of Balazs Lecz nor the names of
 *       contributors may be used to endorse or promote products derived from this
 *       software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

package com.lecz.android.checklists;

import android.app.ExpandableListActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.Toast;

public class ExecuteCheckListActivity extends ExpandableListActivity {
	private long mChecklistId;

	private ChecklistDBAdapter mDB;
	private Cursor mChecklistSectionsCursor;
	private ExpandableListAdapter mAdapter;
	private boolean[] mCheckListSectionChecked;
	private boolean[][] mCheckListItemChecked;
	private Button mBackButton;
	private Button mCheckButton;
	
	private static final int SELECTION_OFFSET_PIXELS = 260;
		
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		mDB = new ChecklistDBAdapter(this).open();
		
		mChecklistId = getIntent().getLongExtra("checklist_id", 0); // TODO(leczbalazs): add assertion
		Cursor checklist = mDB.getChecklist(mChecklistId);
		checklist.moveToFirst(); // FIXME(leczbalazs) add assertion

		Cursor checklistGroup = mDB.getChecklistGroup(checklist.getLong(ChecklistDBAdapter.COLUMN_CHECKLISTS_GROUP_ID));
		checklistGroup.moveToFirst();
		
		setTitle(
			checklistGroup.getString(ChecklistDBAdapter.COLUMN_CHECKLIST_GROUPS_NAME)
			+ " / "
			+ checklist.getString(ChecklistDBAdapter.COLUMN_CHECKLISTS_NAME)
			+ " checklist"
		);
		
		mChecklistSectionsCursor = mDB.getChecklistSections(mChecklistId);
		startManagingCursor(mChecklistSectionsCursor);

		mAdapter = new CheckListItemsListAdapter(
				this,
				mChecklistSectionsCursor,
				android.R.layout.simple_expandable_list_item_1,
				android.R.layout.simple_expandable_list_item_1,
	            new String[] {
						ChecklistDBAdapter.KEY_CHECKLIST_SECTIONS_NAME
					},
	            new int[] {
						android.R.id.text1
					},
	            R.layout.checklist_row_layout,
				new String[] {
						ChecklistDBAdapter.KEY_CHECKLIST_ITEMS_CHALLENGE,
						ChecklistDBAdapter.KEY_CHECKLIST_ITEMS_RESPONSE,
					},
				new int[] {
						R.id.challenge,
						R.id.response,
					}
		);

		setContentView(R.layout.execute_checklist_layout);

		ExpandableListView ev = getExpandableListView();
		ev.setFadingEdgeLength(32);
		ev.setVerticalFadingEdgeEnabled(true);
		ev.setHorizontalFadingEdgeEnabled(true);

//		mBackButton = (Button) findViewById(R.id.back_button);
//		mBackButton.setOnClickListener(new View.OnClickListener() {
//			public void onClick(View arg0) {
//				finish();
//			}
//		});
		
//		mCheckButton = (Button) findViewById(R.id.check_button);
//		mCheckButton.setOnClickListener(new View.OnClickListener() {
//			public void onClick(View arg0) {
//				//TODO(leczbalazs): implement check
//			}
//		});
		
		setListAdapter(mAdapter);
		
		mCheckListSectionChecked = new boolean[mAdapter.getGroupCount()];
		// TODO(leczbalazs): restore values of mCheckListSectionChecked from savedInstanceState

		mCheckListItemChecked = new boolean[mAdapter.getGroupCount()][];
		int groupCount = mAdapter.getGroupCount();
		for (int group = 0; group < groupCount; group++) {
			mCheckListItemChecked[group] = new boolean[mAdapter.getChildrenCount(group)];
		}
		// TODO(leczbalazs): restore values of mCheckListItemChecked from savedInstanceState
			

		// Expand the first section
		ev.expandGroup(0);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		outState.putBooleanArray("CheckListSectionChecked", mCheckListSectionChecked);
	
		int groupCount = mAdapter.getGroupCount();
		for (int group = 0; group < groupCount; group++) {
			mCheckListItemChecked[group] = new boolean[mAdapter.getChildrenCount(group)];
			outState.putBooleanArray("CheckListItemChecked:group:" + group, mCheckListItemChecked[group]);
		}
	}
	
	private boolean isCheckListSectionChecked(int groupPosition) {
		return mCheckListSectionChecked[groupPosition];
	}
	
	private void setCheckListSectionChecked(int groupPosition, boolean value) {
		mCheckListSectionChecked[groupPosition] = value;
	}
	
	private boolean isCheckListItemChecked(int groupPosition, int childPosition) {
		return mCheckListItemChecked[groupPosition][childPosition];
	}
	
	private void setCheckListItemChecked(int groupPosition, int childPosition, boolean value) {
		mCheckListItemChecked[groupPosition][childPosition] = value;
	}
	
	private void toggleCheckListItem(int groupPosition, int childPosition) {
		mCheckListItemChecked[groupPosition][childPosition] = ! mCheckListItemChecked[groupPosition][childPosition];
	}
	
	private int flatPosition(ExpandableListView view, int groupPosition, int childPosition) {
		return view.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
	}
	
	@Override
	public void onGroupExpand(int groupPosition) {
		super.onGroupExpand(groupPosition);
		ExpandableListView ev = getExpandableListView();

		// Expanding the group means starting the checklist, so uncheck all items
		setCheckListSectionChecked(groupPosition, false);

		int childrenCount = mAdapter.getChildrenCount(groupPosition);
		for (int child = 0; child < childrenCount; child++) {
			setCheckListItemChecked(groupPosition, child, false);				
		}

		ev.setSelectionFromTop(flatPosition(ev, groupPosition, 0), SELECTION_OFFSET_PIXELS);
	}
	
	@Override
	public boolean onChildClick(ExpandableListView parent, View v,
			int groupPosition, int childPosition, long id) {

		Log.d("Checklist", "onChildClick: group[" + groupPosition + "] child[" + childPosition + "]");

		toggleCheckListItem(groupPosition, childPosition);
	    parent.invalidateViews();

		// Jump to the next checklist item
		parent.setSelectionFromTop(flatPosition(parent, groupPosition, childPosition + 1), SELECTION_OFFSET_PIXELS);

		// Check if all the items in this section are checked
		int childrenCount = mAdapter.getChildrenCount(groupPosition);
		boolean allChecked = true;
		for (int child = 0; child < childrenCount; child++) {
			if (! isCheckListItemChecked(groupPosition, child)) {
				allChecked = false;
				break;
			}
		}
		if (allChecked) {
			setCheckListSectionChecked(groupPosition, true);
			parent.collapseGroup(groupPosition);
			Toast.makeText(this,
					((Cursor) parent.getItemAtPosition(parent.getFlatListPosition(
							ExpandableListView.getPackedPositionForGroup(groupPosition)))).getString(ChecklistDBAdapter.COLUMN_CHECKLIST_SECTIONS_NAME)
					+ " checklist complete", Toast.LENGTH_SHORT).show();
		}

		return true;
	}

	public class CheckListItemsListAdapter extends SimpleCursorTreeAdapter {
		private Cursor mChecklistItemsCursor;
		
		public CheckListItemsListAdapter(
				Context context,
				Cursor cursor,
				int collapsedGroupLayout,
				int expandedGroupLayout,
				String[] groupFrom,
				int[] groupTo,
				int childLayout,
				String[] childFrom,
				int[] childTo) {
			super(context, cursor, collapsedGroupLayout, expandedGroupLayout, groupFrom,
					groupTo, childLayout, childFrom, childTo);
		}

		@Override
		protected Cursor getChildrenCursor(Cursor groupCursor) {
			mChecklistItemsCursor = mDB.getChecklistItems(groupCursor.getLong(ChecklistDBAdapter.COLUMN_ID));
			startManagingCursor(mChecklistItemsCursor);
			
			return mChecklistItemsCursor;
		}		

		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View v = super.getGroupView(groupPosition, isExpanded, convertView, parent);

			// Set background color according to checked status
			if (isCheckListSectionChecked(groupPosition)) {
				v.setBackgroundColor(parent.getResources().getColor(R.color.checklist_section_checked));
			}
			else {
				v.setBackgroundColor(parent.getResources().getColor(R.color.checklist_section_unchecked));				
			}

			return v;
		}
		
		@Override
		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			View v = super.getChildView(groupPosition, childPosition, isLastChild,
					convertView, parent);
			
			// Set background color according to checked status
			if (isCheckListItemChecked(groupPosition, childPosition)) {
				v.setBackgroundColor(parent.getResources().getColor(R.color.checklist_item_checked));
			}
			else {
				v.setBackgroundColor(parent.getResources().getColor(R.color.checklist_item_unchecked));				
			}
			return v;
		}		
	}
}
